package qos.estimator.tpch;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class TPCHQueryExecutor implements Runnable{
	
	private Map<Integer, String> tpchQueries = new HashMap<Integer, String>();
	private double lambda = 1.0/1200;
	
	public TPCHQueryExecutor() {
		tpchQueries.put(0, TPCHQueries.q0);
		tpchQueries.put(1, TPCHQueries.q1);
		tpchQueries.put(2, TPCHQueries.q2);
		tpchQueries.put(3, TPCHQueries.q3);
		tpchQueries.put(4, TPCHQueries.q4);
		tpchQueries.put(5, TPCHQueries.q5);
		tpchQueries.put(6, TPCHQueries.q6);
		tpchQueries.put(7, TPCHQueries.q7);
		tpchQueries.put(8, TPCHQueries.q8);
		tpchQueries.put(9, TPCHQueries.q9);
		tpchQueries.put(10, TPCHQueries.q10);
		tpchQueries.put(11, TPCHQueries.q11);
		tpchQueries.put(12, TPCHQueries.q12);
		tpchQueries.put(13, TPCHQueries.q13);
		tpchQueries.put(14, TPCHQueries.q14);
		tpchQueries.put(15, TPCHQueries.q15);
		tpchQueries.put(16, TPCHQueries.q16);
		tpchQueries.put(17, TPCHQueries.q17);
		tpchQueries.put(18, TPCHQueries.q18);
		tpchQueries.put(19, TPCHQueries.q19);
		tpchQueries.put(20, TPCHQueries.q20);
		tpchQueries.put(21, TPCHQueries.q21);
		tpchQueries.put(22, TPCHQueries.q22);
	}
	
	public void executeBenchmark() {
		while(true){
			
			new Thread(new Runnable(){

				public void run() {
					int nextQuery = new Random().nextInt(22);
					String query = tpchQueries.get(nextQuery);
					Statement stmt = getStatement();
					try {
						System.out.println("Executing query "+ nextQuery);
						stmt.execute(query);
						stmt.close();
						stmt.getConnection().close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
				
			}).start();
			
			long timeToSleep = (long)scheduleNextExecution()*1000;
			try {
				System.out.println("Scheduling the next execution for "+timeToSleep+"ms");
				Thread.sleep(timeToSleep);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}

	public double scheduleNextExecution() {
		double x = new Random().nextDouble();
		return (-Math.log(1 - x)/lambda);
	}

	protected Statement getStatement() {
		try {
			Class.forName("org.postgresql.Driver");
			Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost/tpch_sf10", "tpch", "tpch");
			return conn.createStatement();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return null;
	}
	
	@Override
	public void run() {
		executeBenchmark();
	}

	
	public static void main(String[] args) {
		TPCHQueryExecutor tpchQuerieExecutor = new TPCHQueryExecutor();
		tpchQuerieExecutor.executeBenchmark();
	}


}
